package org.foj.presenter {
import flash.events.EventDispatcher;

import mx.collections.ArrayCollection;
import mx.collections.ICollectionView;
import mx.controls.Alert;
import mx.managers.CursorManager;
import mx.rpc.AsyncResponder;
import mx.rpc.AsyncToken;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

import org.foj.dto.Issue;
import org.foj.dto.User;
import org.foj.event.EventDispatcherFactory;
import org.foj.event.UIEvent;
import org.foj.event.UserEvent;
import org.foj.model.IssueModel;
import org.foj.view.DetailView;

public class DetailPresenter {

  private var _currentUser:User;
  private var _issue:Issue;
  private var _view:DetailView;
  private var _issueModel:IssueModel;

  public function DetailPresenter(view:DetailView) {
    this._issueModel = new IssueModel();

    _issue = new Issue();
    this._view = view;

    view.issueType.dataProvider = new ArrayCollection(
        ["Bug", "Feature Request", "Enhancement"]
        );
    view.issueSeverity.dataProvider = new ArrayCollection(
        ["Minor", "Major", "Severe"]
        );
    view.issueStatus.dataProvider = new ArrayCollection(
        ["Open", "In Progress", "On Hold", "Finished"]
        );

    EventDispatcherFactory.getEventDispatcher()
        .addEventListener(UIEvent.SELECTED_ISSUE_CHANGED,
        changedIssue);
    EventDispatcherFactory.getEventDispatcher()
        .addEventListener(UIEvent.SAVE_ISSUE_BUTTON_CLICKED,
        saveIssue);
    EventDispatcherFactory.getEventDispatcher()
        .addEventListener(UIEvent.CANCELLED_ISSUE_EDIT,
        cancelChanges);
    EventDispatcherFactory.getEventDispatcher()
        .addEventListener(UserEvent.CURRENT_USER_UPDATED,
        currentUserChanged);
  }

  private function get selectedIssue():Issue {
    return this._issue;
  }

  private function set selectedIssue(issue:Issue):void {
    this._issue = issue;
    _view.issueId.text = issue.id == 0 ? "" : issue.id.toString();
    _view.projectName.text = issue.project;
    _view.issueDescription.text = issue.description;
    _view.issueType.selectedItem = issue.type;
    _view.issueSeverity.selectedItem = issue.severity;
    _view.issueStatus.selectedItem = issue.status;
    _view.issueDetails.text = issue.details;
    _view.issueReportedBy.text = issue.reportedBy;
    _view.issueReportedOn.selectedDate = issue.reportedOn;
    _view.issueAssignedTo.text = issue.assignedTo;
    _view.issueEstimatedHours.text = isNaN(issue.estimatedHours) ?
                                     "" : issue.estimatedHours.toString();
    _view.saveChangesButton.label = issue.id == 0 ?
                                    "Add Issue" : "Save Issue";
  }

  private function saveIssue(event:UIEvent = null):void {
    CursorManager.setBusyCursor();
    _issue.project = _view.projectName.text;
    _issue.description = _view.issueDescription.text;
    _issue.type = String(_view.issueType.selectedItem);
    _issue.severity = String(_view.issueSeverity.selectedItem);
    _issue.status = String(_view.issueStatus.selectedItem);
    _issue.details = _view.issueDetails.text;
    _issue.reportedOn = _view.issueReportedOn.selectedDate;
    _issue.reportedBy = _view.issueReportedBy.text;
    _issue.assignedTo = _view.issueAssignedTo.text;
    _issue.estimatedHours = !isNaN(Number(_view.issueEstimatedHours.text)) ?
                            Number(_view.issueEstimatedHours.text) : null;

    _issueModel.saveIssue(_issue,
        new AsyncResponder(saveIssueResult, handleError));
  }

  private function cancelChanges(event:UIEvent = null):void {
    selectedIssue = new Issue();
    selectedIssue.reportedBy = _currentUser.fullName;
    var event:UIEvent = new UIEvent(UIEvent.SELECTED_ISSUE_CHANGED);
    event.data = selectedIssue;
    EventDispatcherFactory.getEventDispatcher().dispatchEvent(event);
  }

  private function changedIssue(event:UIEvent = null):void {
    CursorManager.removeBusyCursor();
    selectedIssue = event.data;
  }

  private function saveIssueResult(resultEvent:ResultEvent,
                                   token:AsyncToken = null):void {
    CursorManager.removeBusyCursor();
    selectedIssue = new Issue(resultEvent.result);
    var event:UIEvent = new UIEvent(UIEvent.SELECTED_ISSUE_SAVED);
    event.data = _issue;
    EventDispatcherFactory.getEventDispatcher().dispatchEvent(event);
  }

  private function currentUserChanged(event:UserEvent):void {
    _currentUser = event.data;
    if (selectedIssue.id == 0) {
      _view.issueReportedBy.text = _currentUser == null ?
                                   "" :_currentUser.fullName;
    }
  }

  private function handleError(event:FaultEvent,
                               token:AsyncToken = null):void {
    CursorManager.removeBusyCursor();
    Alert.show(event.fault.faultString);
  }
}
}